using System;
using System.Reflection;
using UnityEngine;

namespace BitMango
{
	public static class GameObjectExt
	{
		private static T GetPropValue<T>(object target, string name)
		{
			FieldInfo field = target.GetType().GetField(name);
			if (field != null)
			{
				return (T)((object)field.GetValue(target));
			}
			PropertyInfo property = target.GetType().GetProperty(name);
			if (property != null)
			{
				return (T)((object)property.GetValue(target, null));
			}
			return default(T);
		}

		private static void SetPropValue<T>(object target, string name, T val)
		{
			FieldInfo field = target.GetType().GetField(name);
			if (field != null)
			{
				field.SetValue(target, val);
			}
			PropertyInfo property = target.GetType().GetProperty(name);
			if (property != null)
			{
				property.SetValue(target, val, null);
			}
		}

		public static T CreateTemporaryGameObjectWithComponent<T>() where T : Component
		{
			GameObject gameObject = new GameObject();
			gameObject.name = typeof(T).FullName;
			UnityEngine.Object.DontDestroyOnLoad(gameObject);
			return gameObject.AddComponent<T>();
		}

		public static T CreateTemporaryGameObjectWithComponent<T>(this GameObject thisGO) where T : Component
		{
			GameObject gameObject = new GameObject();
			gameObject.name = typeof(T).FullName;
			UnityEngine.Object.DontDestroyOnLoad(gameObject);
			gameObject.transform.parent = thisGO.transform;
			return gameObject.AddComponent<T>();
		}

		public static T GetOrCreateComponent<T>(this GameObject thisGO) where T : Component
		{
			T component = thisGO.GetComponent<T>();
			if (component == null)
			{
				return thisGO.AddComponent<T>();
			}
			return component;
		}

		public static GameObject CreateGameObjectWithName(this GameObject thisGO, string name)
		{
			return new GameObject
			{
				name = name,
				transform = 
				{
					parent = thisGO.transform,
					localPosition = Vector3.zero
				}
			};
		}

		public static GameObject GetOrCreateGameObjectWithName(this GameObject thisGO, string name)
		{
			Transform transform = thisGO.transform.Find(name);
			if (transform == null)
			{
				transform = new GameObject
				{
					name = name,
					transform = 
					{
						parent = thisGO.transform,
						localPosition = Vector3.zero
					}
				}.transform;
			}
			return transform.gameObject;
		}
	}
}
